<template>
  <ThreeBox ref="container"></ThreeBox>
</template>

<script setup>
import ThreeBox from "../../components/ThreeBox.vue";
import { ref, onMounted } from "vue";
import * as THREE from "../../third/three/three.module.js";
import { Sky } from "../../third/three/jsm/objects/Sky.js";
import { Water } from "../../third/three/jsm/objects/Water1.js";
import { OrbitControls } from "../../third/three/jsm/controls/OrbitControls.js";

const container = ref(null);
let threeBox = null;
let threePara = null;
let scene = new THREE.Scene();
let water = null;

function animate() {
  requestAnimationFrame(animate);
  render();
}

function render() {
  water.material.uniforms["time"].value += 1.0 / 60.0;
  threePara.renderer.render(scene, threePara.camera);
}

function init() {
  //海洋
  let waterGeometry = new THREE.PlaneGeometry(10000, 10000);
  water = new Water(waterGeometry, {
    textureWidth: 512,
    textureHeight: 512,
    waterNormals: new THREE.TextureLoader().load(
      "./three/textures/waternormals.jpg",
      function (texture) {
        texture.wrapS = texture.wrapT = THREE.RepeatWrapping;
      }
    ),
    sunDirection: new THREE.Vector3(),
    sunColor: 0xffffff,
    waterColor: 0x001e0f,
    distortionScale: 3.7,
    fog: scene.fog !== undefined,
  });
  water.rotation.x = -Math.PI / 2;
  scene.add(water);

  //相机
  threePara.camera = new THREE.PerspectiveCamera(
    55,
    threeBox.clientWidth / threeBox.clientHeight,
    1,
    20000
  );
  threePara.camera.position.set(30, 30, 100);

  //渲染器
  threePara.renderer = new THREE.WebGLRenderer();
  threePara.renderer.setPixelRatio(window.devicePixelRatio);
  threePara.renderer.setSize(threeBox.clientWidth, threeBox.clientHeight);
  threePara.renderer.toneMapping = THREE.ACESFilmicToneMapping;
  threeBox.appendChild(threePara.renderer.domElement);

  //天空
  let sky = new Sky();
  sky.scale.setScalar(10000);
  scene.add(sky);

  let sun = new THREE.Vector3();
  sun.setFromSphericalCoords(
    1,
    THREE.MathUtils.degToRad(90 - 2),
    THREE.MathUtils.degToRad(180)
  );
  let skyUniforms = sky.material.uniforms;
  skyUniforms["turbidity"].value = 10;
  skyUniforms["rayleigh"].value = 2;
  skyUniforms["mieCoefficient"].value = 0.005;
  skyUniforms["sunPosition"].value.copy(sun);
  water.material.uniforms["sunDirection"].value.copy(sun).normalize();

  let pmremGenerator = new THREE.PMREMGenerator(threePara.renderer);
  let renderTarget = pmremGenerator.fromScene(sky);
  scene.environment = renderTarget.texture;

  //控制器
  let controls = new OrbitControls(
    threePara.camera,
    threePara.renderer.domElement
  );
  controls.minDistance = 40;
  controls.maxDistance = 200;
}

onMounted(() => {
  threeBox = container.value.threeBox;
  threePara = container.value.threePara;
  init();
  animate();
});
</script>
